#include <fstream>
#include <xmmsclient/xmmsclient++.h>
#include <sys/stat.h>
#include <errno.h>

#include "../config.h"
#include "client.h"
#include "cfg.h"

// ---------------------------------------------
bool Cfg::load()
// ---------------------------------------------
{
	std::string path = Xmms::getUserConfDir() + "/clients/" + PACKAGE;
	if (!ensurePath(path))
	{
		app.getUI()->msg(Ui::NOTICE, "Cfg") << "Could not create the configuration directory." << Ui::END;
		return false;
	}
	
	app.getUI()->msg(Ui::DEBUG, "Cfg") << "Configuration directory is: " << path << Ui::END;

	std::string filepath = path + "/cfg";
	std::ifstream file(filepath.data());

	data.clear();

	if (file.is_open() == false)
	{
		app.getUI()->msg(Ui::VERBOSE, "Cfg") << "Configuration file not found." << Ui::END;
		return false;
	}
	else
	{
		// read config from the file
		app.getUI()->msg(Ui::DEBUG, "Cfg") << "Configuration file found." << Ui::END;

		std::string line;
		std::string section;
		nvpairs_t pairs;
		nvpair_t pair;
		size_t pos;

		while ( std::getline(file, line) )
		{
			pair.first.clear();
			pair.second.clear();
			// skip #comments and empty lines
			if (line[0] != '#' && line.size() != 0)
			{
				pos = line.find_first_of('=');
				if (line[0] == '[' && line[ line.size()-1 ] == ']' )
				{
					// section starter
					data.insert( std::make_pair(section, pairs) );
					pairs.clear();
					section = line.substr(1, line.size()-2);
				}
				else if (pos != std::string::npos)
				{
					// name=value pair
					pair.first = line.substr(0, pos);
					if (pairs.count(pair.first) == 0)
					{
						pair.second.push_back( line.substr(pos+1) );
						pairs.insert( pair );						
					}
					else					
					{
						pairs.find(pair.first)->second.push_back( line.substr(pos+1) );
					}					
				}
			}
		}
		if (pairs.size() != 0)
		{
			data.insert( std::make_pair(section, pairs) );			
		}
	}
	return true;
}

// ---------------------------------------------
std::string Cfg::getPath()
// ---------------------------------------------
{
	std::string o;
	o = Xmms::getUserConfDir() + "/clients/" + PACKAGE;
	return o;
}

// ---------------------------------------------
void Cfg::setPairs(const char* section, const nvpairs_t newdata)
// ---------------------------------------------
{
	std::string str;
	str.assign(section);
	return setPairs(str, newdata);
}

// ---------------------------------------------
void Cfg::setPairs(const std::string section, const nvpairs_t newdata)
// ---------------------------------------------
{
	if (data.count(section) != 0)
	{
		std::map<std::string, nvpairs_t>::iterator i = data.find(section);
		data.erase(section);
	}
	data.insert( std::make_pair(section, newdata) );
}

// ---------------------------------------------
nvpairs_t Cfg::getPairs(const std::string section)
// ---------------------------------------------
{
	nvpairs_t out;
	if (data.count(section) == 0)
	{
		return out;
	}
	return data.find(section)->second;
}

// ---------------------------------------------
bool Cfg::ensurePath(const std::string path)
// ---------------------------------------------
{
	size_t pos;
	struct stat st;
	pos = path.find_first_of('/', 1);
	std::string current;

	while (pos != std::string::npos)
	{
		current = path.substr(0, pos);
		if (stat( current.data(), &st ) != 0)
		{
			if (mkdir(current.data(), 0754) == 0)
			{
				app.getUI()->msg(Ui::VERBOSE, "Cfg") << "Created " << current << Ui::END;
			}
			else
			{
				app.getUI()->msg(Ui::ERROR, "Cfg") << "mkdir: " << strerror(errno) << Ui::END;				
				return false;
			}
		}
		pos = path.find_first_of('/', pos+1);
	}
	return true;
}

// ---------------------------------------------
uri_t Cfg::parseUri(const std::string str)
// ---------------------------------------------
{
	uri_t out;
	size_t s, t, e;
	s = 0;
	e = str.find("://", s);
	if (e != std::string::npos)
	{
		out.scheme = str.substr(s, e-s);
		s = e+3;
		if (str[s] == '[')
		{
			// IPvFuture
			e = str.find_first_of(']', s);
			s++;
			out.host = str.substr(s, e-s);
			s = e+1;
			if (str[s] == ':')
			{
				e = str.find_first_of('/', s);
				s++;
				out.port = str.substr(s, e-s);
				s = e;
			}
			if (str[s] == '/')
			{
				out.path = str.substr(s);
			}
		}
		else
		{
			// IPv4
			t = str.find_first_of(':', s);
			e = str.find_first_of('/', s);
			if (t == std::string::npos && e == std::string::npos)
			{
				// host only
				out.host = str.substr(s);
			}
			else
			if (t != std::string::npos && e == std::string::npos)
			{
				// host+port
				out.host = str.substr(s, t-s);
				out.port = str.substr(++t);
			}
			else
			if (t == std::string::npos && e != std::string::npos)
			{
				// host+path
				out.host = str.substr(s, e-s);
				out.path = str.substr(e);
			}
			else
			if (t < e)
			{
				// host+port+path
				out.host = str.substr(s, t-s);
				t++;
				out.port = str.substr(t, e-t);
				out.path = str.substr(e);
			}
			else
			{
				// host+path
				out.host = str.substr(s, e-s);
				out.path = str.substr(e);
			}
		}
	}
	return out;
}

